/*
 * Copyright (c) 2018. paascloud.net All Rights Reserved.
 * 项目名称：paascloud快速搭建企业级分布式微服务平台
 * 类名称：GlobalExceptionHandler.java
 * 创建人：刘兆明
 * 联系方式：paascloud.net@gmail.com
 * 开源地址: https://github.com/paascloud
 * 博客地址: http://blog.paascloud.net
 * 项目官网: http://paascloud.net
 */

package com.csun.cmny.provider.exception;


import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.base.exception.BusinessException;
import com.csun.cmny.util.PublicUtil;
import com.csun.cmny.util.wrapper.WrapMapper;
import com.csun.cmny.util.wrapper.Wrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.core.task.TaskExecutor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
import java.util.Objects;

/**
 * 全局的的异常拦截器
 *
 * @author paascloud.net @gmail.com
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

	@Resource
	private TaskExecutor taskExecutor;
	@Autowired
	private HttpServletRequest request;
	@Autowired
	private MessageSource messageSource;

	private static final String HEADER_LANGUAGE = "Accept-Language";

	@Value("${spring.profiles.active}")
	String profile;

	@Value("${spring.application.name}")
	String applicationName;

//	@Resource
//	private MdcExceptionLogFeignApi mdcExceptionLogFeignApi;

	/**
	 * 参数非法异常.
	 *
	 * @param e the e
	 *
	 * @return the wrapper
	 */
	@ExceptionHandler(IllegalArgumentException.class)
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public Wrapper illegalArgumentException(IllegalArgumentException e) {
		log.error("参数非法异常={}", e.getMessage(), e);
		return WrapMapper.wrap(ErrorCodeEnum.GL99990100.code(), e.getMessage());
	}

	/**
	 * 业务异常.
	 *
	 * @param e the e
	 *
	 * @return the wrapper
	 */
	@ExceptionHandler(BusinessException.class)
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public Wrapper businessException(BusinessException e) {
		log.error("业务异常={}", e.getMessage(), e);
//		return WrapMapper.wrap(e.getCode() == 0 ? Wrapper.ERROR_CODE : e.getCode(), e.getMessage());
		return WrapMapper.wrap(e.getCode() == 0 ? Wrapper.ERROR_CODE : e.getCode(),
				getLocaleMessage(e.getCode() + "", e.getMessage(), e.getParams()));
	}


	/**
	 * 全局异常.
	 *
	 * @param e the e
	 *
	 * @return the wrapper
	 */
	@ExceptionHandler(Exception.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ResponseBody
	public Wrapper exception(Exception e) {
		log.info("保存全局异常信息 ex={}", e.getMessage(), e);
		taskExecutor.execute(() -> {
//			GlobalExceptionLogDto globalExceptionLogDto = new GlobalExceptionLogDto().getGlobalExceptionLogDto(e, profile, applicationName);
//			mdcExceptionLogFeignApi.saveAndSendExceptionLog(globalExceptionLogDto);
		});
		return WrapMapper.error();
	}

	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	@ResponseBody
	@ExceptionHandler(MultipartException.class)
	public Wrapper multipartException(Throwable t) {
		log.error("上传文件, 出现错误={}", t.getMessage(), t);
		return WrapMapper.wrap(Wrapper.ERROR_CODE, "文件超过限制");
	}

	/**
	 * 获取国际化异常信息
	 */
	private String getLocaleMessage(String code, String defaultMsg, Object[] params) {
		String language = request.getHeader(HEADER_LANGUAGE);
//        String language = request.getParameter("lang");
		Locale locale = Locale.getDefault();
		if (PublicUtil.isNotEmpty(language)) {
			String[] languages = language.split("_");
			if (languages.length == 2) {
				locale = new Locale(languages[0], languages[1]);
				log.debug("current local = {}", locale.toString());
			}
		}
		try {
			return messageSource.getMessage(code, params, locale);
		} catch (Exception e) {
			log.warn("本地化异常消息发生异常: {}, {}", code, params);
			return defaultMsg;
		}
	}
}
